﻿#include "GlobalHelper.h"

#ifdef Q_OS_WIN
#include <windows.h>
#include <tlhelp32.h>
#define WIN32_LEAN_AND_MEAN             // 从 Windows 头文件中排除极少使用的内容
#include <locale>
#endif // Q_OS_WIN

#include <QProcess>
#include <QCoreApplication>
#include <QUuid>
#include <QFile>
#include <QTextStream>
#include <QRegExp>
#include <QDir>
#include <QTime>
#include <QDebug>

#include "ElaMessageBar.h"
#include "IBaseSignal.h"

namespace BaseModule
{

    qint64 GlobalHelper::getTimestamp()
    {
        return QDateTime::currentDateTime().toMSecsSinceEpoch();
    }

    QString GlobalHelper::getTimestampString()
    {
        return QString::number(QDateTime::currentDateTime().toMSecsSinceEpoch());
    }

    void GlobalHelper::sendMsgToParentProcess(QString msg)
    {
        fputs(msg.toLocal8Bit(), stdout);
        fflush(stdout);
    }

    std::wstring GlobalHelper::stringToWString(const std::string data)
    {
        if (!data.size()) return {};

        size_t _len = data.size() + 1;
        wchar_t* _dataW = (wchar_t*)malloc(2 * _len);
        memset(_dataW, 0, 2 * _len);
        size_t _converted = 0;

        std::locale _old_loc = std::locale::global(std::locale(""));
        mbstowcs_s(&_converted, _dataW, _len, data.data(), _TRUNCATE);
        std::locale::global(_old_loc);

        std::wstring _filePath_U = _dataW;
        free(_dataW);
        _dataW = nullptr;

        return _filePath_U;
    }
    qint64 GlobalHelper::getProcessIdByName(std::string processName)
    {
        DWORD processId = 0;
        HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (snapshot != INVALID_HANDLE_VALUE)
        {
            PROCESSENTRY32 processEntry;
            processEntry.dwSize = sizeof(PROCESSENTRY32);
            if (Process32First(snapshot, &processEntry))
            {
                do
                {
                    if (strcmp(processEntry.szExeFile, processName.data()) == 0)
                    {
                        processId = processEntry.th32ProcessID;
                        break;
                    }
                } while (Process32Next(snapshot, &processEntry));
            }
            CloseHandle(snapshot);
        }
        return processId;
    }


    /// @brief 通过进程id关闭进程

    void GlobalHelper::closeProcessByProcessId(qint64 processId)
    {
        HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, processId);
        if (hProcess != NULL)
        {
            TerminateProcess(hProcess, 0);
            CloseHandle(hProcess);
        }
    }


    bool GlobalHelper::readFile(QString filePath, QByteArray& content)
    {
        try
        {
            QFile file(filePath);
            if (!file.exists())
            {
                //emit IBaseSignalInstance->signal_showMessageType((int)BaseModule::MessageType::Error_Message, QObject::tr("Read file fail! file not exist! file path:%1").arg(filePath));
                return false;
            }
            if (!file.open(QIODevice::ReadOnly))
            {
                //emit IBaseSignalInstance->signal_showMessageType((int)BaseModule::MessageType::Error_Message, QObject::tr("Read file fail! open failed! file path:%1").arg(filePath));
                return false;
            }

            QTextStream jsonStream(&file);
            jsonStream.setCodec("UTF-8");
            content = jsonStream.readAll().toUtf8();
            file.close();
            return true;
        }
        catch (const std::exception&)
        {
            //emit IBaseSignalInstance->signal_recordSimulationProcess(int(BaseModule::MessageType::Normal_Message), "catch readFile exception!");
            return false;
        }
    }

    bool GlobalHelper::writeFile(QString filePath, QByteArray content, QIODevice::OpenMode openModel)
    {
        QFile file(filePath);
        if (!file.open(openModel))
        {
            //emit IBaseSignalInstance->signal_showMessageType((int)BaseModule::MessageType::Error_Message, QObject::tr("Write file fail! open failed! file path:%1").arg(filePath));
            return false;
        }
        QTextStream stream(&file);
        stream.setCodec("UTF-8");
        stream << content << "\n";
        file.close();
        return true;
    }

    void GlobalHelper::initProjectTempDir()
    {
        m_installDir = qApp->applicationDirPath().mid(0, qApp->applicationDirPath().lastIndexOf('/'));
        m_tempIODir = m_installDir + "/tempIO";
        createTempDir();
    }

    bool GlobalHelper::createTempDir()
    {
        QDir dir;
        bool result = false;

        //创建tempIO
        if (dir.exists(m_tempIODir))
        {
            result = true;
        }
        else
        {
            result = dir.mkdir(m_tempIODir);
        }
        return (result);
    }

    QString GlobalHelper::getProjectTempIODir()
    {
        return m_tempIODir ;
    }

    /// @brief 判断名字是否合法，只能由字母数字下划线组成、不是空的、长度不大于100
    bool GlobalHelper::isLegalName(QString& name)
    {
        name = name.trimmed();
        bool result = true;
        QString errorMsg;
        if (name.isEmpty())
        {
            //errorMsg = QObject::tr("name is illegal,name can not be empty");
            errorMsg = QStringLiteral("报告名称不能为空");

            result = false;
        }
        else if (name.length() > 32)
        {
            //errorMsg = QObject::tr("name is illegal,the length of the name cannot exceed 100");
            errorMsg = QStringLiteral("报告名称长度不能超过32");
            result = false;
        }
        else
        {
            //仅支持中文、下划线、加号、连字符、数字、英文六种字符
			QRegExp regex1("([\u4e00-\u9fa5a-zA-Z0-9_+-]+)");
            //符号可同时存在但不能连续使用
            QRegExp regex2("^([a-zA-Z0-9\u4e00-\u9fff]+(?:[+_\-][a-zA-Z0-9\u4e00-\u9fff]+)*)+$");
            //不允许文件名以符号开头，文件以中文、字母、数字开头
            QRegExp regex3("([\u4e00-\u9fa5a-zA-Z0-9][\u4e00-\u9fa5a-zA-Z0-9_\-+]*$)");
			if (!regex1.exactMatch(name))
			{
				errorMsg = QStringLiteral("报告名称仅支持中文、下划线（_）、连字符（-）、加号（+）、数字、英文六种字符");
				result = false;
			}
            else if (!regex3.exactMatch(name))
            {
                result = false;
                errorMsg = QStringLiteral("文件名不允许以符号开头");
            }
			else if (!regex2.exactMatch(name))
			{
				result = false;
				errorMsg = QStringLiteral("任意符号不可连续使用");
			}
        }

        if (result)
        {
            return true;
        }
        else
        {
            emit IBaseSignalInstance->signal_sendErrorMessageToUI("报告名称错误");
            return false;
        }
    }

}
